package main

import (
	"fmt"
	"log"
	"sync"
)

type setMap struct {
	sync.RWMutex
	sm map[string]interface{}
}

func (s *setMap) Get(key string) (interface{}, bool) {
	s.RLock()
	defer s.RUnlock()
	if s.sm[key] != nil {
		return s.sm[key], true
	} else {
		log.Printf("不存在map[%v]", key)
		return s.sm[key], false
	}
}

func (s *setMap) Set(key string, value interface{}) {
	// func (s *setMap) Set(key string, value interface{}) *setMap {
	s.Lock()
	s.sm[key] = value
	s.Unlock()
	// return s
}

func (s *setMap) Delete(key string) {
	s.Lock()
	delete(s.sm, key)
	s.Unlock()
	log.Printf("[已删除map[%v]的值]\n", key)
}

func (s *setMap) Add(key string, value interface{}) {
	// func (s *setMap) Add(key string, value interface{}) *setMap {
	// Add方法中调用了上面的Set方法，Set方法中已经加了写锁，如果再加锁会报死锁
	// s.Lock()
	// defer s.Unlock()
	flag := false
	for k, v := range s.sm {
		if key == k {
			log.Printf("[已存在map[%v]%v]\n", k, v)
			// return s
			flag = true
		}
	}
	if !flag {
		s.Set(key, value)
	}

	// return s
}

func main() {
	s := setMap{
		sm: make(map[string]interface{}),
	}

	for i := 0; i < 10; i++ {
		key := fmt.Sprintf("key_%d", i)
		value := i
		s.Set(key, value)
	}
	log.Println("INIT")
	log.Println(s.sm)
	log.Println("SET TEST")
	s.Set("key_1", 999)
	log.Println(s.sm)
	log.Println("ADD TEST")
	s.Add("key_1", 111)
	log.Println(s.sm)
	log.Println("DELETE TEST")
	s.Delete("key_1")
	log.Println(s.sm)
	log.Println("Get TEST")
	value, _ := s.Get("key_20")
	log.Println(value)
	s.Add("key_100", 999)
	log.Println(s.sm)
	s.Delete("key_100")
}

// 可以实现下初始化函数